#include <QDebug>
#include <QDateTime>
#include <QJsonObject>
#include <QJsonDocument>
#include <QEventLoop>
#include <QTimer>
#include <QDateTime>
#include "csyncbasethread.h"
#include "header.h"
#include "ctag.h"

CSyncBaseThread::CSyncBaseThread()
{
    m_bIsConnect = false;
    m_hDb=nullptr;
    m_lpLogCallback=nullptr;
    m_sIp="127.0.0.1";//默认数据库IP地址为本机IP地址
    m_nPort=8005;//默认数据库端口号
    m_sUserName = "admin";
    m_sDbName = "";
    m_sPassWd = "";
    m_nDbId = -1;
    m_bIsInit = false;
    m_bhread.store(false);
    m_bShouldStop = false;
    m_bFrist=true;
}

CSyncBaseThread::~CSyncBaseThread()
{
    ThreadStop();
    m_bShouldStop = true;
	sync_Logout(m_hDb);
    sync_Close(m_hDb);
    sync_DestoryDB(m_hDb);
    quit();
    wait();
}

int CSyncBaseThread::addTag(const QString &addr, const int &nType, const unsigned int &cyc)
{
    Q_UNUSED(cyc);
	m_mutex.lock();
	if (addr == "")
	{
		return -1;
	}
	CTag* pTag = new CTag(addr.toStdString(), nType);
	if (pTag == nullptr)
	{
		return -1;
	}
	if (m_vecTag.m_mapTag.contains(addr))
	{
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("添加测点失败,测点重复添加").toStdString().c_str(),ELogType::enSysAlarm);
        }
		QString sLog = A2T("添加测点失败,测点重复添加");
		m_log.AddMsg(FL, _Q(sLog));
		return -1;
	}
	m_vecTag.m_mapTag.insert(addr,pTag);
	m_bIsInit = false;
	m_mutex.unlock();
	return 0;
}

int CSyncBaseThread::delTag(const QString &addr)
{
	m_mutex.lock();
	if (!m_vecTag.m_mapTag.contains(addr))
	{
		m_mutex.unlock();
		return -1;
	}

	delete m_vecTag.m_mapTag[addr];
	m_vecTag.m_mapTag[addr]=nullptr;
	m_vecTag.m_mapTag.remove(addr);
	m_bIsInit = false;
	m_mutex.unlock();
    return 1;
}

void CSyncBaseThread::clear()
{
	m_mutex.lock();
	SAFE_DELETE_A(m_vecTag.m_pTagId);
	SAFE_DELETE_A(m_vecTag.m_pTagData);
	SAFE_DELETE_A(m_vecTag.m_pTagQuality);
	for (auto i = m_vecTag.m_mapTag.begin(); i != m_vecTag.m_mapTag.end(); i++)
	{
		CTag* pTag = i.value();
		delete pTag;
		pTag = nullptr;
	}
	m_vecTag.m_mapTag.clear();
	m_vecTag.m_mapTagId.clear();
	m_bIsInit = false;
	m_mutex.unlock();
}

CTag* CSyncBaseThread::value(const QString &addr)
{
	if (addr == "")
		return nullptr;
	if (!m_bIsConnect || !m_bIsInit)
	{
		return nullptr;
	}
	CTag* pTag = nullptr;
	m_mutex.lock();
	if (m_vecTag.m_mapTag.contains(addr))
	{
		pTag = m_vecTag.m_mapTag[addr];
	}
	m_mutex.unlock();
	return pTag;
}

VecPTag CSyncBaseThread::values(const VecStr &vecAddr)
{
	VecPTag vecpTag;
	vecpTag.clear();
	if (vecAddr.size() == 0)
	{
		return vecpTag;
	}
	m_mutex.lock();
	for (int i = 0; i < vecAddr.size(); i++)
	{
		if (m_vecTag.m_mapTag.contains(QString::fromStdString(vecAddr[i])))
		{
			vecpTag.push_back(m_vecTag.m_mapTag[QString::fromStdString(vecAddr[i])]);
		}
	}
	m_mutex.unlock();
	return vecpTag;
}

int CSyncBaseThread::setValue(const QString &addr, const CTag* pTag)
{
	if (addr == "" || pTag==nullptr)
	{
		return -1;
	}
	if (pTag->sAddr != addr)
	{
		return -1;
	}
	m_mutex.lock();
	if (m_vecTag.m_mapTag.contains(addr))
	{
		m_vecTag.m_mapTag[addr]->setValue(*pTag);
		m_mutex.unlock();
		return 0;
	}
	else
	{
		m_mutex.unlock();
		return -1;
    }
}

int CSyncBaseThread::setValue(const QString &addr, CTag &Tag)
{
    if (addr == "")
    {
        return -1;
    }
    if (Tag.sAddr != addr)
    {
        return -1;
    }
    m_mutex.lock();
    if (m_vecTag.m_mapTag.contains(addr))
    {
        m_vecTag.m_mapTag[addr]->setValue(Tag);
        m_mutex.unlock();
        return 0;
    }
    else
    {
        m_mutex.unlock();
        return -1;
    }
}

int CSyncBaseThread::setValues(const VecStr &vecAddr, VecPTag vecTags)
{
	if (vecAddr.size() == 0 || vecTags.size() == 0)//传入的参数无效
	{
		return -1;
	}
	if (vecAddr.size() != vecTags.size())//传入的参数不合法
	{
		return -1;
	}
	m_mutex.lock();
	for (int i = 0; i < vecAddr.size(); i++)
	{
		if (m_vecTag.m_mapTag.contains(QString::fromStdString(vecAddr[i])))
		{
			CTag* pTag = m_vecTag.m_mapTag[QString::fromStdString(vecAddr[i])];
			pTag->setValue(*vecTags[i]);
		}
	}
	m_mutex.unlock();
    return 0;
}

int CSyncBaseThread::setValueHistory(QString addr, CTag* pTag)
{
    if (addr == "" || pTag==nullptr)
    {
        return -1;
    }
    if (pTag->sAddr != addr)
    {
        return -1;
    }
    m_mutex.lock();
    if (m_vecTag.m_mapTagHis.contains(addr))
    {
        m_vecTag.m_mapTagHis[addr]->setValue(*pTag);
        m_mutex.unlock();
        return 0;
    }
    else
    {
        m_vecTag.m_mapTagHis.insert(addr,pTag);
        m_vecTag.m_mapTagHis[addr]->setValue(*pTag);
        m_mutex.unlock();
        return 0;
    }
}

int CSyncBaseThread::setValueHistory(QString addr, CTag &Tag)
{
    if (addr == "")
    {
        return -1;
    }
    if (Tag.sAddr != addr)
    {
        return -1;
    }
    m_mutex.lock();
    if (m_vecTag.m_mapTagHis.contains(addr))
    {
        m_vecTag.m_mapTagHis[addr]->setValue(Tag);
        m_mutex.unlock();
        return 0;
    }
    else
    {
        CTag* pTag = new CTag(Tag);
        m_vecTag.m_mapTagHis.insert(addr, pTag);
        m_mutex.unlock();
        return 0;
    }
}

//int CSyncBaseThread::setValuesHistory(const VecStr &vecAddr, VecPTag vecTags)
//{
//    if (vecAddr.size() == 0 || vecTags.size() == 0)//传入的参数无效
//    {
//        return -1;
//    }
//    if (vecAddr.size() != vecTags.size())//传入的参数不合法
//    {
//        return -1;
//    }
//    m_mutex.lock();
//    for (int i = 0; i < vecAddr.size(); i++)
//    {
//        if (m_vecTag.m_mapTagHis.contains(QString::fromStdString(vecAddr[i])))
//        {
//            CTag* pTag = m_vecTag.m_mapTagHis[QString::fromStdString(vecAddr[i])];
//            pTag->setValue(*vecTags[i]);
//        }
//        else
//        {
//            m_vecTag.m_mapTagHis.insert(QString::fromStdString(vecAddr[i]),vecTags[i]);
//            m_vecTag.m_mapTagHis[QString::fromStdString(vecAddr[i])]->setValue(*vecTags[i]);
//        }
//    }
//    m_mutex.unlock();
//    return 0;
//}

int CSyncBaseThread::setValuesHistory(const VecStr &vecAddr, VecPTag vecTags)
{
    if (vecAddr.size() == 0 || vecTags.size() == 0)//传入的参数无效
    {
        return -1;
    }
    if (vecAddr.size() != vecTags.size())//传入的参数不合法
    {
        return -1;
    }
    m_mutex.lock();
    STagHistory stTagHistory;
    for (int i = 0; i < vecTags.size(); i++)
    {
        stTagHistory.vecTag.push_back(vecTags[i]);
    }
    m_vecTag.m_vecTagHis.prepend(stTagHistory);
    m_mutex.unlock();
    return 0;
}


void CSyncBaseThread::setLogRet(LogCallback callback)
{
    m_lpLogCallback=callback;
}

void CSyncBaseThread::writeTag()
{
	int nCount = 0;
	QString strLog = "";
	if (!m_vecTag.m_mapTag.isEmpty())
	{
		nCount = m_vecTag.m_mapTag.count();
		int nSendNum = 0;
		TAG_DATA *pTagData = m_vecTag.m_pTagData;
		for (auto i = m_vecTag.m_mapTag.begin(); i != m_vecTag.m_mapTag.end(); ++i)
		{
			CTag* pTag = i.value();
			if (NULL == pTag) continue;
            pTagData[nSendNum].nTagId = m_vecTag.m_mapTagId[QString::fromStdString(pTag->sAddr)];
            MS_TIME struTime = timestampToMS_TIME(pTag->timeStamp);
			memcpy(&(pTagData[nSendNum].TagData.tmTime), &struTime, sizeof(struTime));
            pTagData[nSendNum].TagData.Val.vt = valueTypeChange(pTag->type);
            pTagData[nSendNum].TagData.nQuality = pTag->quality;
			double dVal = 0.0;
			pTag->getValue(&dVal);
			assignmentTag(pTagData[nSendNum].TagData.Val.val,pTag);
			nSendNum++;
		}
		if (nSendNum > nCount)
		{
            if(m_lpLogCallback!=nullptr)
            {
                m_lpLogCallback(A2T("批量写普通测点数据失败，测点数量错误").toStdString().c_str(),ELogType::enSysAlarm);
            }
			strLog = A2T("批量写普通测点数据失败，测点数量错误");
			m_log.AddMsg(FL, _Q(strLog));
            return ;
		}
		//调用批量写数据函数
		int nWriteTagNum = sync_WriteRealData(m_hDb, pTagData, nSendNum);
		if (nWriteTagNum != nSendNum)
		{
            if(m_lpLogCallback!=nullptr)
            {
                m_lpLogCallback(A2T("批量写普通测点数据失败，数据数量：%1，实际数量：%2").arg(nSendNum).arg(nWriteTagNum).toStdString().c_str(),ELogType::enSysAlarm);
            }
			strLog = A2T("批量写普通测点数据失败，数据数量：%1，实际数量：%2").arg(nSendNum).arg(nWriteTagNum);
			m_log.AddMsg(FL, _Q(strLog));
        }
    }
}

//void CSyncBaseThread::writeTagHistory()
//{
//    if (m_vecTag.m_mapTagHis.size() > 0)
//    {
//        int nCount = m_vecTag.m_mapTagHis.count();
//        int nSendNum = 0;
//        TAG_DATA *pTagData  = new TAG_DATA[nCount];
//        memset(pTagData, 0, nCount * sizeof(TAG_DATA));
//        for (auto i = m_vecTag.m_mapTagHis.begin(); i != m_vecTag.m_mapTagHis.end(); ++i)
//        {
//            CTag* pTag = i.value();
//            if (NULL == pTag) continue;
//            pTagData[nSendNum].nTagId = m_vecTag.m_mapTagId[QString::fromStdString(pTag->sAddr)];
//            MS_TIME struTime = timestampToMS_TIME(pTag->timeStamp);
//            memcpy(&(pTagData[nSendNum].TagData.tmTime), &struTime, sizeof(struTime));
//            pTagData[nSendNum].TagData.Val.vt = valueTypeChange(pTag->type);
//            pTagData[nSendNum].TagData.nQuality = pTag->quality;
//            double dVal = 0.0;
//            pTag->getValue(&dVal);
//            assignmentTag(pTagData[nSendNum].TagData.Val.val,pTag);
//            nSendNum++;
//        }
//        if (nSendNum > nCount)
//        {
//            if(m_lpLogCallback!=nullptr)
//            {
//                m_lpLogCallback(A2T("批量写历史测点数据失败，测点数量错误").toStdString().c_str(),ELogType::enSysAlarm);
//            }
//            QString strLog = A2T("批量写历史测点数据失败，测点数量错误");
//            m_log.AddMsg(FL, _Q(strLog));
//            return ;
//        }
//        //调用批量写数据函数
//        int nWriteTagNum = sync_WriteHisData(m_hDb, pTagData, nSendNum);
//        if (nWriteTagNum != nSendNum)
//        {
//            if(m_lpLogCallback!=nullptr)
//            {
//                m_lpLogCallback(A2T("批量写历史测点数据失败，数据数量：%1，实际数量：%2").arg(nSendNum).arg(nWriteTagNum).toStdString().c_str(),ELogType::enSysAlarm);
//            }
//            QString strLog = A2T("批量写历史测点数据失败，数据数量：%1，实际数量：%2").arg(nSendNum).arg(nWriteTagNum);
//            m_log.AddMsg(FL, _Q(strLog));
//        }
//    }
//}

void CSyncBaseThread::writeTagHistory()
{
    if (m_vecTag.m_vecTagHis.size() == 0)   return;
    auto itor = m_vecTag.m_vecTagHis.begin();
    while (itor != m_vecTag.m_vecTagHis.end())
    {
        //超过重试次数的删除
        if (itor->nUploadTimes >= itor->nUploadLimit)
        {
            itor->vecAddr.clear();
            foreach (CTag* pTag, itor->vecTag)
            {
                SAFE_DELETE(pTag);
            }
            itor = m_vecTag.m_vecTagHis.erase(itor);
            continue;
        }
        int nCount = itor->vecTag.count();
        int nSendNum = 0;
        TAG_DATA *pTagData  = new TAG_DATA[nCount];
        memset(pTagData, 0, nCount * sizeof(TAG_DATA));
        //赋值所有发送的测点
        for (int i = 0; i < nCount; i++)
        {
            CTag* pTag = itor->vecTag[i];
            pTagData[nSendNum].nTagId = m_vecTag.m_mapTagId[QString::fromStdString(pTag->sAddr)];
            qDebug() << "nTagId" << pTagData[nSendNum].nTagId << "pTag->sAddr" << pTag->sAddr;
            MS_TIME struTime = timestampToMS_TIME(pTag->timeStamp);
            memcpy(&(pTagData[nSendNum].TagData.tmTime), &struTime, sizeof(struTime));
            pTagData[nSendNum].TagData.Val.vt = valueTypeChange(pTag->type);
            pTagData[nSendNum].TagData.nQuality = pTag->quality;
            double dVal = 0.0;
            pTag->getValue(&dVal);
            assignmentTag(pTagData[nSendNum].TagData.Val.val, pTag);
            MS_TIME tmSend = pTagData[nSendNum].TagData.tmTime;
            qDebug() << "ID" << pTagData[nSendNum].nTagId << "Time" << QString("%1-%2-%3-%4-%5-%6")
                        .arg(tmSend.year).arg(tmSend.mon).arg(tmSend.day).arg(tmSend.hour).arg(tmSend.min).arg(tmSend.sec)
                     << "Type" << pTagData[nSendNum].TagData.Val.vt << "Quality" << pTagData[nSendNum].TagData.nQuality;
            nSendNum++;
        }
        if (nSendNum > nCount)
        {
            if(m_lpLogCallback != nullptr)
            {
                m_lpLogCallback(A2T("批量写历史测点数据失败，测点数量错误").toStdString().c_str(),ELogType::enSysAlarm);
            }
            QString strLog = A2T("批量写历史测点数据失败，测点数量错误");
            m_log.AddMsg(FL, _Q(strLog));
            itor->nUploadTimes++;
            itor++;
            continue;
        }
        //调用批量写数据函数
        int nWriteTagNum = sync_WriteHisData(m_hDb, pTagData, nSendNum);
        //上传失败则报错且累积次数重传
        //if (nWriteTagNum != nSendNum)
        if (nWriteTagNum != 1)      //写历史数据无论写入多少返回都是1
        {
            if (m_lpLogCallback != nullptr)
            {
                m_lpLogCallback(A2T("批量写历史测点数据失败，数据数量：%1，实际数量：%2").arg(nSendNum).arg(nWriteTagNum).toStdString().c_str(),ELogType::enSysAlarm);
            }
            QString strLog = A2T("批量写历史测点数据失败，数据数量：%1，实际数量：%2").arg(nSendNum).arg(nWriteTagNum);
            m_log.AddMsg(FL, _Q(strLog));
            itor->nUploadTimes++;
        }
        //上传成功则将上传数据体全部清空
        else
        {
            SAFE_DELETE_A(pTagData);
            itor->vecAddr.clear();
            foreach (CTag* pTag, itor->vecTag)
            {
                SAFE_DELETE(pTag);
            }
            itor = m_vecTag.m_vecTagHis.erase(itor);
            continue;
        }
        ++itor;
    }
}

bool CSyncBaseThread::assignmentTag(D_VAL &val, CTag* pTag)
{
	bool bRet = true;
	QString strLog = "";
    switch (pTag->type)
	{
	case CTag::enUnknown:
        val.fval = pTag->toFloat();
		break;
	case CTag::enUint8:
        val.bval = pTag->toUint8();
		break;
	case CTag::enInt16:
        val.ival = (int32)pTag->toInt16();
		break;
	case CTag::enUint16:
        val.uival = (uint32)pTag->toUint16();
		break;
	case CTag::enInt32:
        val.lval = pTag->toInt32();
		break;
	case CTag::enUint32:
        val.ulval = pTag->toUint32();
		break;
	case CTag::enInt64:
        val.i64val = pTag->toInt64();
		break;
	case CTag::enUint64:
        val.i64val = pTag->toUint64();
		break;
	case CTag::enFloat:
	{
		float fData = pTag->toFloat();
        val.fval = fData;
		break;
	}
	case CTag::enDouble:
        val.dval = pTag->toDouble();
		break;
	case CTag::enString:
		val.pstr = new char[strlen(pTag->value.str)];
		memcpy(val.pstr, pTag->value.str, strlen(pTag->value.str));
		break;
	default:
		bRet = false;
		break;
	}
	return bRet;
}

uint8 CSyncBaseThread::valueTypeChange(const int &nType)
{
	uint8 nReType;
	switch (nType)
	{
	case CTag::enUnknown:
		nReType = DT_FLOAT;
		break;
	case CTag::enUint8:
		nReType = DT_BOOL;
		break;
	case CTag::enInt16:
		nReType = DT_INT;
		break;
	case CTag::enUint16:
		nReType = DT_UINT;
		break;
	case CTag::enInt32:
		nReType = DT_INT;
		break;
	case CTag::enUint32:
		nReType = DT_UINT;
		break;
	case CTag::enInt64:
		nReType = DT_LONG;
		break;
	case CTag::enUint64:
		nReType = DT_ULONG;
		break;
	case CTag::enFloat:
		nReType = DT_FLOAT;
		break;
	case CTag::enDouble:
		nReType = DT_DOUBLE;
		break;
	case CTag::enString:
		nReType = DT_STR;
		break;
	default:
		nReType = DT_FLOAT;
		break;
	}
    return nReType;
}

MS_TIME CSyncBaseThread::timestampToMS_TIME(uint64_t timestamp)
{
    MS_TIME ms_time;
    QDateTime dtm = QDateTime::fromMSecsSinceEpoch(timestamp);
    QTime time = dtm.time();
    ms_time.msec = (short)time.msec();
    ms_time.sec = (quint8)time.second();
    ms_time.min = (quint8)time.minute();
    ms_time.hour = (quint8)time.hour();
    QDate date = dtm.date();
    ms_time.day = (quint8)date.day();
    ms_time.mon = (quint8)date.month();
    ms_time.year = (quint8)(date.year() - 2000);

    return ms_time;
}

void CSyncBaseThread::run()
{
    while (!m_bShouldStop)
    {
        if (!m_bhread.load())
        {
            msleep(50);
            continue;
        }
        //数据库未连接
        if (false == isSyncBaseConnect())
        {
            QThread::msleep(1000);
            continue;
        }
        //首次执行或测点集合发生变化的时候重新获取一下测点ID
        initTag();

        //写测点
        writeTag();
        //写历史测点
        writeTagHistory();
        msleep(1000);
        continue;
    }
}

void CSyncBaseThread::ThreadStart()
{
    if (!m_bhread.load())
    {
        if (m_bFrist)
        {
            start();
            m_bFrist = false;
        }
        m_bhread.store(true);
    }
}

void CSyncBaseThread::ThreadStop()
{
    if (m_bhread.load())
    {
        m_bhread.store(false);
    }
}

void CSyncBaseThread::config(const QString& sIp, const int& nPort, const QString& sUserName, const QString& sPassWd, const QString& sDbName)
{
	m_mutex.lock();
	m_sIp = sIp;
	m_nPort = nPort;
	m_sUserName = sUserName;
	m_sPassWd = sPassWd;
	m_sDbName = sDbName;
	m_mutex.unlock();
}

QString CSyncBaseThread::getConfig()
{
	QJsonObject jsonObj;
	jsonObj["sIp"] = m_sIp;
	jsonObj["nPort"] = m_nPort;
	jsonObj["sUserName"] = m_sUserName;
	jsonObj["sPassWd"] = m_sPassWd;
	jsonObj["sDbName"] = m_sDbName;

	// 将 JSON 对象转换为字符串
	QJsonDocument jsonDoc(jsonObj);
	QString jsonString = jsonDoc.toJson(QJsonDocument::Indented); // 格式化输出
	return jsonString;
}

bool CSyncBaseThread::startSyncBase()
{
	return connectSyncBase();
}

bool CSyncBaseThread::stopSyncBase()
{
	return disconnectSyncBase();
}

bool CSyncBaseThread::connectSyncBase()
{
	if (m_bIsConnect)
		return true;
	if (isSyncBaseConnect()) return true;
    if(m_hDb==nullptr)
    {
        m_hDb = sync_CreateDB();
    }
    QString strLog;
    //打开数据库
    bool bRet = openDb();
    if (false == bRet)
    {
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("sync_open fail, Ip:%1, port:%2, 打开数据库失败").arg(m_sIp).arg(m_nPort).toStdString().c_str(),ELogType::enSysAlarm);
        }
        strLog = A2T("sync_open fail, Ip:%1, port:%2, 打开数据库失败").arg(m_sIp).arg(m_nPort);
        m_log.AddMsg(FL, _Q(strLog));
        return false;
    }
    //登录数据库
    bRet = loginDb();
    if (false == bRet)
    {
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("sync_login fail, user:%1, password:%2, 数据库登录失败").arg(m_sUserName).arg(m_sPassWd).toStdString().c_str(),ELogType::enSysAlarm);
        }
        strLog = A2T("sync_login fail, user:%1, password:%2, 数据库登录失败").arg(m_sUserName).arg(m_sPassWd);
        m_log.AddMsg(FL, _Q(strLog));
        return false;
    }
    //获取数据库Id
	bRet = getBaseId();
	if (false == bRet)
	{
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("getBaseId失败,数据库名:%1").arg(m_sDbName).toStdString().c_str(),ELogType::enSysAlarm);
        }
		strLog = A2T("getBaseId失败,数据库名:%1").arg(m_sDbName);
		m_log.AddMsg(FL, _Q(strLog));
		return false;
	}
    if(m_lpLogCallback!=nullptr)
    {
        m_lpLogCallback(A2T("syncbase 连接成功").toStdString().c_str(),ELogType::enWorkInfo);
    }
    strLog = A2T("syncbase connect success");
    m_log.AddMsg(FL, _Q(strLog));
    return true;
}

bool CSyncBaseThread::disconnectSyncBase()
{
	if (false == isSyncBaseConnect()) return true;
	QString strLog = "";
	//登出数据库
	int nRet = sync_Logout(m_hDb);
	if (0 == nRet)
	{
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("sync_Logout fail, 数据库登出失败").toStdString().c_str(),ELogType::enSysAlarm);
        }
		strLog = A2T("sync_Logout fail, 数据库登出失败");
		m_log.AddMsg(FL, _Q(strLog));
		return false;
	}
	//关闭数据库
	nRet = sync_Close(m_hDb);
	if (0 == nRet)
	{
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("sync_Close, 数据库关闭失败").toStdString().c_str(),ELogType::enSysAlarm);
        }
        strLog = A2T("sync_Close, 数据库关闭失败");
		m_log.AddMsg(FL, _Q(strLog));
		return false;
	}
	nRet = sync_DestoryDB(m_hDb);
	if (0 == nRet)
	{
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("sync_DestoryDB, 数据库关闭失败").toStdString().c_str(),ELogType::enSysAlarm);
        }
        strLog = A2T("sync_DestoryDB, 数据库关闭失败");
		m_log.AddMsg(FL, _Q(strLog));
		return false;
	}
	m_hDb = nullptr;
	m_bIsConnect = false;
    if(m_lpLogCallback!=nullptr)
    {
        m_lpLogCallback(A2T("syncbase 断开连接成功").toStdString().c_str(),ELogType::enOperInfo);
    }
	strLog = A2T("syncbase disconnect success");
	m_log.AddMsg(FL, _Q(strLog));
	return true;
}

void CSyncBaseThread::createDb()
{
    m_hDb=sync_CreateDB();
    if(m_hDb==nullptr)
    {
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("调用sync_CreateDb失败，创建syncbase数据库对象失败").toStdString().c_str(),ELogType::enSysAlarm);
        }
        QString strLog = A2T("调用sync_CreateDb失败，创建syncbase数据库对象失败");
        m_log.AddMsg(FL, _Q(strLog));
    }
}

int CSyncBaseThread::openDb()
{
    int nRet=sync_Open(m_hDb,_QStr2CharStr(m_sIp),m_nPort);
    if(nRet!=1)
    {
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("调用sync_Open失败").toStdString().c_str(),ELogType::enSysAlarm);
        }
        QString strLog = A2T("调用sync_Open失败");
        m_log.AddMsg(FL, _Q(strLog));
    }
    return nRet;
}

int CSyncBaseThread::closeDb()
{
	int nRet = sync_Close(m_hDb);
	if (nRet != 1)
	{
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("调用sync_Close失败").toStdString().c_str(),ELogType::enSysAlarm);
        }
        QString strLog = A2T("调用sync_Close失败");
		m_log.AddMsg(FL, _Q(strLog));
	}
	return nRet;
}

int CSyncBaseThread::loginDb()
{
    int nRet=sync_Login(m_hDb,_QStr2CharStr(m_sUserName),_QStr2CharStr(m_sPassWd));
    if(nRet!=1)
    {
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("调用sync_Login失败").toStdString().c_str(),ELogType::enSysAlarm);
        }
        QString strLog = A2T("调用sync_Login失败");
        m_log.AddMsg(FL, _Q(strLog));
    }
    return nRet;
}

int CSyncBaseThread::logoutDb()
{
    int nRet=sync_Logout(m_hDb);
    if(nRet!=1)
    {
        if(m_lpLogCallback!=nullptr)
        {
            m_lpLogCallback(A2T("调用sync_Logout失败").toStdString().c_str(),ELogType::enSysAlarm);
        }
        QString strLog = A2T("调用sync_Logout失败");
        m_log.AddMsg(FL, _Q(strLog));
    }
    return nRet;
}

bool CSyncBaseThread::isSyncBaseConnect()
{
    if(m_hDb==nullptr)
    {
        return false;
    }
    bool bRet = (bool)sync_IsOpened(m_hDb);
    return bRet;
}

bool CSyncBaseThread::getBaseId()
{
    if (m_sDbName.isEmpty() || (NULL == m_hDb))
    {
        m_nDbId = -1;
        return false;
    }
    int nId = sync_GetBaseIdByName(m_hDb, _Q(m_sDbName), m_sDbName.length());
    if (nId < 0)
    {
        m_nDbId = -1;
        return false;
    }
    m_nDbId = nId;
	return true;
}

void CSyncBaseThread::initTag()
{
    if(m_hDb==nullptr)
        return;
    if(m_bIsInit)
        return;
	m_mutex.lock();
    int nCount=m_vecTag.m_mapTag.count();
	if (0 == nCount)
	{
		m_mutex.unlock();
		return;
	}
    //开始获取各个测点的测点ID
    SAFE_DELETE_A(m_vecTag.m_pTagId);
    m_vecTag.m_pTagId = new TAGID[nCount];
	memset(m_vecTag.m_pTagId, 0, nCount*sizeof(TAGID));

    SAFE_DELETE_A(m_vecTag.m_pTagData);
    m_vecTag.m_pTagData = new TAG_DATA[nCount];
	memset(m_vecTag.m_pTagData, 0, nCount * sizeof(TAG_DATA));

    SAFE_DELETE_A(m_vecTag.m_pTagQuality);
    m_vecTag.m_pTagQuality = new char[nCount];
	memset(m_vecTag.m_pTagQuality, 0, nCount * sizeof(char));
	m_vecTag.m_mapTagId.clear();

	int n = 0;
    for (auto i = m_vecTag.m_mapTag.begin(); i != m_vecTag.m_mapTag.end(); i++)
    {
		CTag* pTag = i.value();
        int nId = sync_GetTagIdByName(m_hDb,m_nDbId,pTag->sAddr,strlen(pTag->sAddr));
        if (nId < 0)
        {
            m_vecTag.m_pTagId[n] = -1;
			m_vecTag.m_pTagData[n].nTagId = -1;
			m_vecTag.m_mapTagId.insert(QString::fromStdString(pTag->sAddr), -1);
            if(m_lpLogCallback != nullptr)
            {
                m_lpLogCallback(A2T("根据测点名获取测点ID失败，测点名为:%1").arg(pTag->sAddr).toStdString().c_str(),ELogType::enSysAlarm);
            }
            QString strLog = A2T("根据测点名获取测点ID失败，测点名为:%1").arg(pTag->sAddr);
            m_log.AddMsg(FL, _Q(strLog));
            continue;
        }
        m_vecTag.m_pTagId[n] = nId;
		m_vecTag.m_pTagData[n].nTagId = nId;
        m_vecTag.m_mapTagId.insert(QString::fromStdString(pTag->sAddr), nId);
        qDebug() << A2T("根据测点名获取测点ID成功，测点名为:%1,ID为:%2").arg(pTag->sAddr).arg(nId);
		n++;
    }
    m_bIsInit=true;
	m_mutex.unlock();
}

void CSyncBaseThread::readTag()
{
	m_mutex.lock();
    int nCount=m_vecTag.m_mapTag.count();
    if(nCount == 0)
    {
        return;
    }
    int nReCount=sync_ReadRealData(m_hDb, m_vecTag.m_pTagId, m_vecTag.m_pTagData, nCount);
    if(nReCount == nCount)
    {
        analysisReadData();
    }
	m_mutex.unlock();
}

void CSyncBaseThread::analysisReadData()
{
    QString strLog = "";
    int nCount = m_vecTag.m_mapTag.count();
	int n = 0;
    for (auto i = m_vecTag.m_mapTag.begin(); i != m_vecTag.m_mapTag.end(); ++i)
    {
        CTag *pTag = i.value();
		if (NULL == pTag) continue;
		QString sAddr = i.key();
		TAGID nId;
		if (m_vecTag.m_mapTagId.contains(sAddr))
		{
			nId = m_vecTag.m_mapTagId[sAddr];
		}
		TAG_DATA TagData;
		bool bFind = false;
		for (int n = 0; n < m_vecTag.m_mapTag.count(); n++)
		{
			if (nId == m_vecTag.m_pTagId[n])
			{
				bFind = true;
				TagData = m_vecTag.m_pTagData[n];
				break;
			}
		}
		if (!bFind)
		{
			continue;
		}
        switch (pTag->type)
        {
		case CTag::enUnknown:
            pTag->setValue(TagData.TagData.Val.val.fval);
            break;
		case CTag::enUint8:
			pTag->setValue(TagData.TagData.Val.val.bval);
			break;
		case CTag::enInt16:
			pTag->setValue(TagData.TagData.Val.val.fval);
			break;
		case CTag::enUint16:
			pTag->setValue(TagData.TagData.Val.val.fval);
			break;
		case CTag::enInt32:
			pTag->setValue(TagData.TagData.Val.val.ival);
			break;
		case CTag::enUint32:
			pTag->setValue(TagData.TagData.Val.val.uival);
			break;
		case CTag::enInt64:
			pTag->setValue(TagData.TagData.Val.val.i64val);
			break;
		case CTag::enUint64:
			pTag->setValue(TagData.TagData.Val.val.i64val);
			break;
		case CTag::enFloat:
			pTag->setValue(TagData.TagData.Val.val.fval);
			break;
		case CTag::enDouble:
			pTag->setValue(TagData.TagData.Val.val.dval);
			break;
		case CTag::enString:
			pTag->setValue(std::string(TagData.TagData.Val.val.pstr));
			break;
        default:
            break;
        }
    }
}
